﻿using System.Collections.Generic;
using System.IO;
using JetBrains.Annotations;
using UnityEngine;

namespace com.susi.ui {
    public class UIManager : MonoBehaviour {
        private const  string UIManagerPrefabResourcePath = "GameManager/UIManager";
        internal const string WndPrefabResourcePath       = "GameManager/Windows";

        private Dictionary<string, IWnd> Loaded = new Dictionary<string, IWnd>();

        [NotNull]
        public static UIManager Instance {
            get {
                if (_Instance == null) {
                    Load();
                }

                return _Instance;
            }
        }

        private static UIManager _Instance;

        public static Canvas Root => _Instance.RootCanvas;

        [SerializeField]
        private Canvas RootCanvas;

        public static void Load()
        {
            var exist = GameObject.FindObjectOfType<UIManager>();
            if (exist != null) {
                _Instance = exist;
                return;
            }

            exist = Resources.Load<UIManager>(UIManagerPrefabResourcePath);
            if (exist == null) throw new FileNotFoundException($"Can't load UIManager", UIManagerPrefabResourcePath);
            _Instance = Instantiate(exist);
        }
       
        private void Awake()
        {
            if (Instance == null) {
                _Instance = this;
            }
            else if (object.ReferenceEquals(Instance, this) == false) {
                DestroyImmediate(gameObject);
            }
        
            DontDestroyOnLoad(Instance);
        }

        public IWnd LoadWnd(string wndname)
        {
            if (Loaded.TryGetValue(wndname, out var wnd)) {
                return wnd.OnMulLoad();
            }

            return LoadWndFromResource(wndname);
        }

        public IWnd LoadWndFromResource(string wndname)
        {
            var path   = $"{WndPrefabResourcePath}/{wndname}";
            var loaded = Resources.Load(path) as GameObject;
            if (loaded == null) {
                Debug.LogWarning($"[warn][{path}]load fail.");
                return null;
            }

            var inScene = Instantiate(loaded, UIManager.Root.transform, true);
            // DestroyImmediate(loaded);

            var wnd = inScene.GetComponent<IWnd>();
            if (wnd == null) {
                Debug.LogWarning($"[warn][{path}]load successes but get {nameof(IWnd)} fail.");
                DestroyImmediate(inScene);
                return null;
            }

            Loaded.Add(wndname, wnd);

            return wnd;
        }
    }
}